﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace CNFProblem.CNF
{
    /// <summary>
    /// Parsuje wyrażenia zapisane w następującej formie:
    /// [~]nazwa1 [~]nazwa2 [~]nazwa3
    /// [~]nazwa4 [~]nazwa5 [~]nazwa6
    /// ...
    /// W każdej linni '~' jest opcjonalne i oznacza zanegowanie zmiennej. [~]nazwa stanowi pojedynczy lireral a.
    /// Nie moze byc przerwy miedzy ~ a zmienna.
    /// W linni zmienne są poddawane alternatywie a miedzy liniami - koniunkcji
    /// </summary>
    class Parser
    {
        public const char negation = '~';

        /// <summary>
        /// Parsuje ciag znakow do LogicalFormula3CNF
        /// </summary>
        /// <param name="input">Ciag wejsciowy</param>
        /// <returns>Formula</returns>
        public static LogicalFormula3CNF Parse(string input)
        {
            string[] lines = input.Split('\n');
            LogicalFormula3CNF formula = new LogicalFormula3CNF();
            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i].Trim();
                string[] tokens = line.Split(' ');
                if (tokens.Length == 0) continue;
                if (tokens.Length > 3) throw new ArgumentException("Nieprawidłowy format danych wejściowych w linii " + i);
                LiteralAlternative la = new LiteralAlternative(tokens.Length);
                for (int j = 0; j < tokens.Length; j++)
                {
                    if (tokens[j].Length == 0) throw new ArgumentException("Nieprawidłowy format danych wejściowych w linii " + i);
                    if (tokens[j][0] == negation)
                    {
                        la.SetNeg(j, true);
                        tokens[j] = tokens[j].Substring(1);
                    }
                    int id = formula.Variables.Add(tokens[j]);
                    la.SetId(j, id);
                }

                formula.Add(la);
            }

            return formula;
        }
    }
}
